﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Permission.cs" company="">
//   
// </copyright>
// <summary>
//   许可对象。用于定义角色(&lt;see cref="Role" /&gt;)是否有权对资源(通过ResourceId属性定义)进行某种操作(&lt;see cref="Operator" /&gt;)
// </summary>
// --------------------------------------------------------------------------------------------------------------------

using System;
using Ornament.Domain;

namespace Ornament.MemberShip.Permissions
{
    public class GenericPermission<T> : Permission
    {
        public GenericPermission() { }
        public GenericPermission(T res)
            : base(res)
        {
        }

        public virtual new T Resource { get { return (T)base.Resource; } set { base.Resource = value; } }
    }

    /// <summary>
    /// 许可对象。用于定义角色(<see cref="Role"/>)是否有权对资源(通过ResourceId属性定义)进行某种操作(<see cref="Operator"/>)
    /// </summary>  
    public abstract class Permission : DomainObject<Guid>
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="Permission"/> class.
        /// </summary>
        protected Permission()
        {
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="res"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException">res is null</exception>
        /// <exception cref="ArgumentNullException">id is null</exception>
        /// <exception cref="ArgumentNullException">id is null</exception>
        public static Permission CreatePermission(object res)
        {
            if (res == null)
            {
                throw new ArgumentNullException("res");
            }

            var typeString = String.Format("Ornament.MemberShip.Permissions.GenericPermission`1[[{0}]],Ornament.MemberShip.Core", res.GetType().FullName);
            var t = Type.GetType(typeString);
            if (t == null)
                throw new MemberShipPermissionException("Can not find the type with " + typeString);
            var a = (Permission)Activator.CreateInstance(t);
            a.Resource = res;
            return a;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="res"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException">res is null</exception>
        public static Permission CreatePermission(Type res)
        {
            var typeString =
                String.Format("Ornament.MemberShip.Permissions.GenericPermission`1[[{0}]],Ornament.MemberShip.Core", res.AssemblyQualifiedName);
            var t = Type.GetType(typeString);
            if (t == null)
                throw new MemberShipPermissionException("Can not find the type with " + typeString);
            return (Permission)Activator.CreateInstance(t);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="info">Resources's info</param>
        protected Permission(object info)
        {
            Resource = info;
        }

        /// <summary>
        /// Gets or sets permission's name .
        /// </summary>
        /// <value>The name.</value>
        public virtual string Name { get; set; }

        /// <summary>
        /// Gets or sets the remark.
        /// </summary>
        /// <value>The comment.</value>
        public virtual string Remark { get; set; }

        /// <summary>
        /// Gets or sets Resource
        /// </summary>
        /// <value>Resource</value>
        public virtual object Resource { get; set; }

        /// <summary>
        /// Gets or sets OperatorValues. 拥有操作的数值
        /// </summary>
        /// <value>
        /// The operator values.
        /// </value>
        public virtual int Operator { get; set; }


        /// <summary>
        /// Toes the operator.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public virtual T ToOperator<T>()
        {
            return (T)Enum.ToObject(typeof(T), Operator);
        }

        /// <summary>
        /// Determines whether the specified operators has operator.
        /// </summary>
        /// <param name="operators">The operators.</param>
        /// <returns>
        /// 	<c>true</c> if the specified operators has operator; otherwise, <c>false</c>.
        /// </returns>
        public virtual bool HasOperator(Enum operators)
        {
            int os = Convert.ToInt32(operators);
            if (Operator < os)
                return false;
            return (Operator & os) == os;
        }

        public override int GetHashCode()
        {
            return (Name + Operator).GetHashCode();
        }

        public override string ToString()
        {
            return this.Name;
        }
    }
}